package com.gylang.print.pdf.render;

import ch.qos.logback.core.util.CloseUtil;
import cn.hutool.core.collection.CollUtil;
import com.gylang.print.pdf.domain.PdfInfo;
import com.gylang.print.pdf.domain.PdfPageWrapper;
import com.gylang.print.pdf.domain.PdfWrapper;
import com.gylang.print.pdf.domain.component.BasePdfComponent;
import com.gylang.print.pdf.domain.component.img.ImgComponent;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDDocumentInformation;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.springframework.beans.BeanUtils;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * @author gylang
 * data 2021/6/6
 */
public class PdfRenderHelper {

	private static final Map<String, IPdfRender> RENDER_POOL = new HashMap<>();

	static {
		// 内置
		TextPdfRender textPdfRender = new TextPdfRender();
		RENDER_POOL.put(textPdfRender.type(), textPdfRender);
		ImgPdfRender imgPdfRender = new ImgPdfRender();
		RENDER_POOL.put(imgPdfRender.type(), imgPdfRender);
		TableRender tableRender = new TableRender();
		RENDER_POOL.put(tableRender.type(), tableRender);
	}

	public static PDDocument render(PdfWrapper pdfWrapper) throws IOException {

		// 生成pdf
		if (null == pdfWrapper.getDocument()) {
			pdfWrapper.setDocument(new PDDocument());
		}
		PDDocument document = pdfWrapper.getDocument();
		// metadata
		PdfInfo pdfInfo = pdfWrapper.getPdfInfo();
		if (null != pdfInfo) {
			PDDocumentInformation documentInformation = document.getDocumentInformation();
			BeanUtils.copyProperties(pdfInfo, documentInformation);
			Optional.of(pdfInfo.getCustomMetadata()).ifPresent(m -> m.forEach(documentInformation::setCustomMetadataValue));
		}
		// 创建页面
		for (PdfPageWrapper pageWrapper : pdfWrapper.getPdfPageWrapperList()) {


			PDPage page = pageWrapper.getPage();
			if (null == page) {
				PDRectangle rectangle = new PDRectangle(pageWrapper.getWidth(), pageWrapper.getHeight());
				pageWrapper.setPage(new PDPage(rectangle));
				pageWrapper.setPdfWrapper(pdfWrapper);
				document.addPage(pageWrapper.getPage());
			}
		// 渲染背景
			ImgComponent background = pageWrapper.getBackground();
			if (null != background) {
				// 渲染背景
				background.setPageWrapper(pageWrapper);
				background.setWidth(pageWrapper.getWidth());
				background.setHeight(pageWrapper.getHeight());
				renderByType(pdfWrapper, pageWrapper, background);
			}
			//渲染组件
			if (CollUtil.isNotEmpty(pageWrapper.getPdfComponents())) {
				for (BasePdfComponent pdfComponent : pageWrapper.getPdfComponents()) {
					pdfComponent.setPageWrapper(pageWrapper);
					IPdfRender<BasePdfComponent> pdfRender = RENDER_POOL.get(pdfComponent.getType());
					pdfRender.render(pdfWrapper, pageWrapper, pdfComponent);
				}
			}
			// 关闭流
			CloseUtil.closeQuietly(pageWrapper.getContentStream());
			pageWrapper.setContentStream(null);
		}

		// 渲染完成
		return document;
	}

	public static void renderByType(PdfWrapper pdfWrapper, PdfPageWrapper pageWrapper, BasePdfComponent component) {
		RENDER_POOL.get(component.getType()).render(pdfWrapper, pageWrapper, component);
	}
}
